/**
 * @file LoggerManager.cpp
 * @brief 日志管理器实现
 * @author Enterprise Logger Team
 * @date 2024
 */

#include "LoggerManager.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <cstring>
#include <chrono>
#include <iomanip>
#include <algorithm>
#include <cctype>

// 简单的JSON解析（避免外部依赖）
#include <algorithm>
#include <cctype>

namespace logger
{

    // 静态成员定义
    LoggerManager *LoggerManager::instance_ = nullptr;

    LoggerManager::~LoggerManager()
    {
        shutdown();
    }

    bool LoggerManager::init(const LogConfig &config)
    {
        std::lock_guard<std::mutex> lock(mutex_);

        if (initialized_)
        {
            std::cerr << "Logger already initialized" << std::endl;
            return false;
        }

        config_ = config;

        // 设置日志级别
        Logger::setLogLevel(config_.minLevel);

        // 生成基于当前时间的目录名
        std::string timestampDir = generateTimestampDirectory();
        std::string fullLogDirectory = config_.logDirectory + "/" + timestampDir;

        // 创建基础日志目录和时间戳子目录（如果不存在）
        // 注意：C++17有std::filesystem，但为了兼容性使用系统命令
#ifdef _WIN32
        std::string baseCmd =
            "if not exist \"" + config_.logDirectory + "\" mkdir \"" + config_.logDirectory + "\"";
        std::string fullCmd =
            "if not exist \"" + fullLogDirectory + "\" mkdir \"" + fullLogDirectory + "\"";
#else
        std::string baseCmd = "mkdir -p " + config_.logDirectory;
        std::string fullCmd = "mkdir -p " + fullLogDirectory;
#endif
        system(baseCmd.c_str());
        system(fullCmd.c_str());

        // 更新配置中的日志目录为完整路径
        config_.logDirectory = fullLogDirectory;

        if (config_.asyncMode)
        {
            // 创建异步日志器
            std::string logPath = fullLogDirectory + "/" + config_.moduleName;
            asyncLogger_.reset(new AsyncLogger(logPath, config_.maxFileSize, config_.flushInterval));

            // 设置输出函数
            instance_ = this;
            Logger::setOutput(asyncOutput);

            // 启动异步日志线程
            asyncLogger_->start();
        }
        else
        {
            // 同步模式：直接输出到文件
            // 这里可以扩展实现同步文件输出
            std::cerr << "Sync mode not fully implemented, using console output" << std::endl;
        }

        initialized_ = true;

        // 输出初始化信息
        LOG_INFO << "Logger initialized successfully"
                 << " | Module: " << config_.moduleName
                 << " | Level: " << static_cast<int>(config_.minLevel)
                 << " | Mode: " << (config_.asyncMode ? "Async" : "Sync")
                 << " | Directory: " << timestampDir;

        return true;
    }

    bool LoggerManager::initFromFile(const std::string &configFile)
    {
        std::ifstream file(configFile);
        if (!file.is_open())
        {
            std::cerr << "Failed to open config file: " << configFile << std::endl;
            return false;
        }

        // 简单的配置文件解析（每行一个配置项）
        LogConfig config;
        std::string line;

        while (std::getline(file, line))
        {
            // 去除空白字符
            line.erase(std::remove_if(line.begin(), line.end(), ::isspace), line.end());

            // 跳过空行和注释
            if (line.empty() || line[0] == '#' || line[0] == '/')
            {
                continue;
            }

            // 解析 key=value 格式
            size_t pos = line.find('=');
            if (pos != std::string::npos)
            {
                std::string key = line.substr(0, pos);
                std::string value = line.substr(pos + 1);

                // 去除引号
                if (!value.empty() && value[0] == '"' && value[value.length() - 1] == '"')
                {
                    value = value.substr(1, value.length() - 2);
                }

                // 设置配置项
                if (key == "moduleName")
                {
                    config.moduleName = value;
                }
                else if (key == "logDirectory")
                {
                    config.logDirectory = value;
                }
                else if (key == "maxFileSize")
                {
                    config.maxFileSize = parseFileSize(value);
                }
                else if (key == "flushInterval")
                {
                    config.flushInterval = std::stoi(value);
                }
                else if (key == "minLevel")
                {
                    // 解析日志级别
                    if (value == "TRACE")
                        config.minLevel = logger::LogLevel::TRACE_LEVEL;
                    else if (value == "DEBUG")
                        config.minLevel = logger::LogLevel::DEBUG_LEVEL;
                    else if (value == "INFO")
                        config.minLevel = logger::LogLevel::INFO_LEVEL;
                    else if (value == "WARN")
                        config.minLevel = logger::LogLevel::WARN_LEVEL;
                    else if (value == "ERROR")
                        config.minLevel = logger::LogLevel::ERROR_LEVEL;
                    else if (value == "FATAL")
                        config.minLevel = logger::LogLevel::FATAL_LEVEL;
                }
                else if (key == "asyncMode")
                {
                    config.asyncMode = (value == "true" || value == "1");
                }
                else if (key == "consoleOutput")
                {
                    config.consoleOutput = (value == "true" || value == "1");
                }
            }
        }

        file.close();
        return init(config);
    }

    void LoggerManager::shutdown()
    {
        std::lock_guard<std::mutex> lock(mutex_);

        if (!initialized_)
        {
            return;
        }

        LOG_INFO << "Shutting down logger...";

        if (asyncLogger_)
        {
            asyncLogger_->stop();
            asyncLogger_.reset();
        }

        // 恢复默认输出
        Logger::setOutput([](const char *msg, int len)
                          { fwrite(msg, 1, len, stdout); });

        initialized_ = false;
        instance_ = nullptr;
    }

    void LoggerManager::setLogLevel(LogLevel level)
    {
        Logger::setLogLevel(level);
        config_.minLevel = level;
    }

    LogLevel LoggerManager::getLogLevel() const
    {
        return Logger::logLevel();
    }

    void LoggerManager::flush()
    {
        if (asyncLogger_)
        {
            // 异步日志器会定期自动刷新
            // 这里可以添加强制刷新逻辑
            asyncLogger_->flush();
        }
    }

    void LoggerManager::asyncOutput(const char *msg, int len)
    {
        if (instance_ && instance_->asyncLogger_)
        {
            // 写入异步日志缓冲区
            instance_->asyncLogger_->append(msg, len);

            // 如果配置了控制台输出，同时输出到控制台
            if (instance_->config_.consoleOutput)
            {
                fwrite(msg, 1, len, stdout);
            }
        }
        else
        {
            // 降级到标准输出
            fwrite(msg, 1, len, stdout);
        }
    }

    std::string LoggerManager::generateTimestampDirectory() const
    {
        // 获取当前时间
        auto now = std::chrono::system_clock::now();
        auto time_t = std::chrono::system_clock::to_time_t(now);

        // 转换为本地时间
        std::tm tm_time;
#ifdef _WIN32
        localtime_s(&tm_time, &time_t);
#else
        localtime_r(&time_t, &tm_time);
#endif

        // 格式化为 YYYYMMDD_HHMMSS
        std::ostringstream oss;
        oss << std::setfill('0') << std::setw(4) << (tm_time.tm_year + 1900) << std::setw(2)
            << (tm_time.tm_mon + 1) << std::setw(2) << tm_time.tm_mday << "_" << std::setw(2)
            << tm_time.tm_hour << std::setw(2) << tm_time.tm_min << std::setw(2) << tm_time.tm_sec;

        return oss.str();
    }

    uint64_t LoggerManager::parseFileSize(const std::string &sizeStr) const
    {
        if (sizeStr.empty())
        {
            return 1073741824; // 默认1GB
        }

        std::string str = sizeStr;
        // 转换为大写以便统一处理
        std::transform(str.begin(), str.end(), str.begin(), ::toupper);

        // 查找数字部分的结束位置
        size_t numEnd = 0;
        while (numEnd < str.length() && (std::isdigit(str[numEnd]) || str[numEnd] == '.'))
        {
            numEnd++;
        }

        if (numEnd == 0)
        {
            std::cerr << "Invalid file size format: " << sizeStr << ", using default 1GB" << std::endl;
            return 1073741824;
        }

        // 提取数字部分
        double number = std::stod(str.substr(0, numEnd));

        // 提取单位部分
        std::string unit = str.substr(numEnd);

        // 去除空白字符
        unit.erase(std::remove_if(unit.begin(), unit.end(), ::isspace), unit.end());

        // 计算最终大小
        uint64_t multiplier = 1;
        if (unit.empty() || unit == "B" || unit == "BYTES")
        {
            multiplier = 1;
        }
        else if (unit == "K" || unit == "KB" || unit == "KILOBYTES")
        {
            multiplier = 1024;
        }
        else if (unit == "M" || unit == "MB" || unit == "MEGABYTES")
        {
            multiplier = 1024 * 1024;
        }
        else if (unit == "G" || unit == "GB" || unit == "GIGABYTES")
        {
            multiplier = 1024ULL * 1024 * 1024;
        }
        else if (unit == "T" || unit == "TB" || unit == "TERABYTES")
        {
            multiplier = 1024ULL * 1024 * 1024 * 1024;
        }
        else
        {
            std::cerr << "Unknown file size unit: " << unit << ", treating as bytes" << std::endl;
            multiplier = 1;
        }

        uint64_t result = static_cast<uint64_t>(number * multiplier);

        std::cout << "Parsed file size: " << sizeStr << " -> " << result << " bytes" << std::endl;

        return result;
    }

} // namespace logger
